package com.jse.pay;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

import org.nutz.http.Request;
import org.nutz.http.Sender;
import org.nutz.ioc.impl.PropertiesProxy;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
import org.nutz.lang.Times;
import org.nutz.lang.util.NutMap;
import org.nutz.log.Log;
import org.nutz.log.Logs;

import com.github.wxpay.sdk.WXPayUtil;
import com.jse.dao.Dao;
import com.jse.util.IP;

public class WxPay {

	Log log = Logs.get();
	
	PropertiesProxy conf;
	
	Dao dao;

	/**
	 * 
	 * @param param title id orderno price openid
	 * @return
	 */
	public Map<Object,Object> getH5(Map<String, Object> data) {
		NutMap param=NutMap.WRAP(data);
		String appid = param.getString("wxpay.appid");
		if(Strings.isEmpty(appid)) {
			appid = conf.get("wxpay.appid");
		}
		String mch_id = param.getString("wxpay.mch_id");// 商户号
		if(Strings.isEmpty(mch_id)) {
			mch_id = conf.get("wxpay.mch_id");// 商户号
		}
		String key = param.getString("wxpay.key");
		if(Strings.isEmpty(key)) {
			key = conf.get("wxpay.key");
		}
		String openid = param.getString("openid");// openid 用户微信id
		String body = param.getString("title");
		String out_trade_no = param.getString("orderno");// 订单号
		String attach = param.getString("id");// 附加数据 原样返回
		String totalFee = getMoney(param.getString("price"));// 总金额以分为单位，不带小数点
		String spbill_create_ip = IP.getIP();// 订单生成的机器 IP
		String notify_url = conf.get("wxpay.notify_url");// 通知
		String trade_type = "JSAPI";
		String nonce_str = WXPayUtil.generateNonceStr();// 随机字符串
		
		try {
			SortedMap<String, String> packageParams = new TreeMap<String, String>();
			packageParams.put("appid", appid);
			packageParams.put("mch_id", mch_id);
			packageParams.put("nonce_str", nonce_str);
			packageParams.put("body", body);
			packageParams.put("attach", attach);
			packageParams.put("out_trade_no", out_trade_no);
			packageParams.put("total_fee", totalFee);
			packageParams.put("spbill_create_ip", spbill_create_ip);
			packageParams.put("notify_url", notify_url);
			packageParams.put("trade_type", trade_type);
			packageParams.put("openid", openid);
			String sign = WXPayUtil.generateSignature(packageParams, key);
			packageParams.put("sign", sign);// 加密
			String requestXML = WXPayUtil.generateSignedXml(packageParams, key);
			log.info("支付请求：" + requestXML);
			String resXml = Sender
					.create(Request.post("https://api.mch.weixin.qq.com/pay/unifiedorder").setData(requestXML)).send()
					.getContent();
			log.info("支付结果：" + resXml);
			Map<String, String> map = WXPayUtil.xmlToMap(resXml);
			SortedMap<Object,Object> ret = new TreeMap<Object,Object>();
			ret.put("appId", appid);
			ret.put("timeStamp", WXPayUtil.getCurrentTimestamp());
			ret.put("nonceStr", map.get("nonce_str"));
			ret.put("package", "prepay_id=" + map.get("prepay_id"));
			ret.put("signType", "MD5");
			String signStr=createSign(ret,key);
			ret.put("paySign", signStr);
			return ret;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 获取扫描支付url
	 * 
	 * @param map{
	 *            title id orderno price
	 *            notify_url 通知地址 product_id 商品id }
	 * @return
	 */
	public String getQrcode(NutMap param) {
		String appid = conf.get("wxpay.appid");
		String mch_id = conf.get("wxpay.mch_id");// 商户号
		String key = conf.get("wxpay.key");
		String notify_url = conf.get("wxpay.notify_url");// 通知
		String body = param.getString("title");
		String out_trade_no = param.getString("orderno");// 订单号
		String nonce_str = WXPayUtil.generateNonceStr();// 随机字符串
		String product_id = param.getString("id");// 商品id 扫描必填
		String spbill_create_ip = IP.getIP();
		String totalFee = getMoney(param.getString("price"));// 总金额以分为单位，不带小数点
		try {

			// 正式上线的时候价格根据订单id查询
//			String order_price = "1"; // 价格 注意：价格的单位是分
			
			SortedMap<String, String> packageParams = new TreeMap<String, String>();
			packageParams.put("appid", appid);
			packageParams.put("mch_id", mch_id);
			packageParams.put("nonce_str", nonce_str);
			packageParams.put("body", body);
			packageParams.put("out_trade_no", out_trade_no);
			packageParams.put("total_fee", totalFee);
			packageParams.put("spbill_create_ip", spbill_create_ip);
			packageParams.put("notify_url", notify_url);
			packageParams.put("trade_type", "NATIVE");
			packageParams.put("product_id", product_id);// 商品id
			Calendar nowTime = Calendar.getInstance();
			packageParams.put("time_start", Times.format("yyyyMMddHHmmss", nowTime.getTime()));
			nowTime.add(Calendar.DATE, 1);
			packageParams.put("time_expire", Times.format("yyyyMMddHHmmss", nowTime.getTime()));

			String sign = WXPayUtil.generateSignature(packageParams, key);
			packageParams.put("sign", sign);// 加密

			String requestXML = WXPayUtil.generateSignedXml(packageParams, key);
			log.info("支付请求：" + requestXML);
			String resXml = Sender
					.create(Request.post("https://api.mch.weixin.qq.com/pay/unifiedorder").setData(requestXML)).send()
					.getContent();
			log.info("支付结果：" + resXml);
			Map<String, String> map = WXPayUtil.xmlToMap(resXml);
			// 交易保障
			String codeurl = "";
			if (map.get("return_code").toString().equals("SUCCESS")
					&& map.get("result_code").toString().equals("SUCCESS")) {
				codeurl = map.get("code_url");// 微信二维码短链接

			} else {
				log.info(map.get("err_code_des"));
			}
			return codeurl;
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		return "";
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public boolean notify(HashMap tbl) {
		try {
			tbl.put(".table", "wxpay");
			dao.insert(tbl);
		} catch (Exception e) {
			log.error(e);
		}
		try {
			boolean result=tbl.get("return_code").equals("SUCCESS");
			return result;
		} catch (Exception e) {
			log.error(e);
		}
		return false;
	}
	
	/**
	 * 元转换成分
	 * 
	 * @param money
	 * @return
	 */
	public static String getMoney(String amount) {
		if (amount == null) {
			return "";
		}
		// 金额转化为分为单位
		String currency = amount.replaceAll("\\$|\\￥|\\,", ""); // 处理包含, ￥ 或者$的金额
		int index = currency.indexOf(".");
		int length = currency.length();
		Long amLong = 0l;
		if (index == -1) {
			amLong = Long.valueOf(currency + "00");
		} else if (length - index >= 3) {
			amLong = Long.valueOf((currency.substring(0, index + 3)).replace(".", ""));
		} else if (length - index == 2) {
			amLong = Long.valueOf((currency.substring(0, index + 2)).replace(".", "") + 0);
		} else {
			amLong = Long.valueOf((currency.substring(0, index + 1)).replace(".", "") + "00");
		}
		return amLong.toString();
	}
	
	public void setConf(PropertiesProxy conf) {
		this.conf = conf;
	}

	public void setDao(Dao dao) {
		this.dao = dao;
	}
	
	@SuppressWarnings("rawtypes")
	public static String createSign(SortedMap<Object,Object> parameters,String key){  
        StringBuffer sb = new StringBuffer();  
        Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序（升序）  
        Iterator it = es.iterator();  
        while(it.hasNext()) {  
            Map.Entry entry = (Map.Entry)it.next();  
            String k = (String)entry.getKey();  
            Object v = entry.getValue();  
            if(null != v && !"".equals(v)   
                    && !"sign".equals(k) && !"key".equals(k)) {  
                sb.append(k + "=" + v + "&");  
            }  
        }  
        sb.append("key=" + key);
        String sign = Lang.md5(sb.toString()).toUpperCase();  
        return sign;  
    }

	public static void main(String[] args) {

		// data.put("wxpay_appid", "wx2787c3302c182d65");
		// data.put("wxpay_mch_id", "1289729501");
		// data.put("wxpay_key", "6e332d87778242619fd832c1bc85d12f");
		// data.put("body","商品信息");
		// data.put("spbill_create_ip","219.142.254.120");
		// data.put("total_fee","100");
		// data.put("device_info", "WEB");
		// data.put("nonce_str",UUID.randomUUID().toString().replace("-", ""));
		// data.put("notify_url", "http://www.iepsy.com/pay/wx_notify");
		// data.put("detail", "商品");
		// data.put("attach", "心教育");
		// data.put("out_trade_no", "17012318170009");
		// data.put("fee_type", "CNY");
		// data.put("total_fee", "60");
		// data.put("product_id", "xxxxx11111");
		// System.err.println(getQrcode(data));

		// 公众号支付
//		data.put("wxpay_appid", "wx2787c3302c182d65");
//		data.put("wxpay_mch_id", "1289729501");
//		data.put("wxpay_key", "6e332d87778242619fd832c1bc85d12f");
//		// data.put("secret", "46d29cfb91416dd55822661840c29d14");
//		data.put("openid", "oHStSs_tYVWk92RMF0w_QwVUjzIg");
//		data.put("body", "商品信息");
//		data.put("spbill_create_ip", "219.142.254.120");
//		data.put("total_fee", "100");
//		data.put("device_info", "WEB");
//		data.put("nonce_str", UUID.randomUUID().toString().replace("-", ""));
//		data.put("notify_url", "http://www.iepsy.com/pay/wx_notify");
//		data.put("detail", "商品");
//		data.put("attach", "心教育");
//		data.put("out_trade_no", "17012318170029");
//		data.put("fee_type", "CNY");
//		data.put("total_fee", "60");

	}
}
